home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Http Server / •OT_Classes / TNetworkSession.cp < prev    next >
Encoding:
Text File  |  1996-01-11  |  10.5 KB  |  378 lines  |  [TEXT/CWIE]

  1. //    TNetworkSession.cp - Macintosh OpenTransport Network Server class object
  2. // 
  3. // Apple Macintosh Developer Technical Support
  4. // Written by:  Vinne Moscaritolo
  5. //
  6. //  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
  7. //
  8. // You may incorporate this sample code into your applications without
  9. // restriction, though the sample code has been provided "AS IS" and the
  10. // responsibility for its operation is 100% yours.  However, what you are
  11. // not permitted to do is to redistribute the source as "DSC Sample Code"
  12. // after having made changes. If you're going to re-distribute the source,
  13. // we require that you make it clear in the source that the code was
  14. // descended from Apple Sample Code, but that you've made changes.
  15. // 
  16.  
  17. #include "TNetworkSession.h"
  18. #include "TNetworkAcceptor.h"
  19.  
  20.  
  21. // ---------------------------------------------------------------------------
  22. //     NotifyProc (queue up an event)
  23. // ---------------------------------------------------------------------------
  24. //     TNetworkSession OT Notifier Proc  
  25.  
  26. pascal void TNetworkSession::NotifyProc( TNetworkSession* theSession, OTEventCode theEvent, OTResult theResult, void* theParam)
  27. {    
  28.     try
  29.     {
  30. //// No-copy memory was released
  31.             if(theEvent == T_MEMORYRELEASED) TNetworkBuf::Release(theParam); 
  32.             
  33. // Data avail at endpoint
  34.             else if (theEvent == T_DATA)  theSession->EventDataAvail();
  35.         
  36. // queue all others
  37.                 else QUEUE_NET_EVENT( theSession, theEvent, theResult, theParam);
  38.     }
  39.  
  40.     catch (TNetworkException &ex)
  41.     {
  42.                 DebugStr("\p TNetworkSession::NotifyProc -- Network Exception.. ");
  43.     }
  44.     
  45.     catch(TMacException &ex)
  46.     {
  47.                 DebugStr("\p TNetworkSession::NotifyProc -- Mac Exception.. ");
  48.     }
  49.     
  50.     catch(...)        // catch everything
  51.     {
  52.                 DebugStr("\p TNetworkSession::NotifyProc -- Other Exception.. ");
  53.     } 
  54.     
  55. }
  56.  
  57.  
  58. // ---------------------------------------------------------------------------
  59. //     TNetworkSession
  60. // ---------------------------------------------------------------------------
  61. //    Default Constructor
  62.  
  63. TNetworkSession::TNetworkSession(TNetworkAcceptor* theServer) 
  64. {
  65.     TNetworkEndpointDescriptor* theEPD;
  66.     
  67. // Setup a new endpoint
  68.     fEndPoint = kOTInvalidEndpointRef;
  69.     fData            = nil;
  70.     fServer         = theServer;
  71.     
  72.     theEPD = theServer->GetEPD();
  73.     
  74.   ThrowIfOTErr( ::OTAsyncOpenEndpoint(theEPD->GetConfiguration() ,0,&fInfo, NotifyProc, this ) );
  75.  
  76. }
  77.  
  78. // ---------------------------------------------------------------------------
  79. //     ~TNetworkListener
  80. // ---------------------------------------------------------------------------
  81. //    Destructor
  82.  
  83. TNetworkSession::~TNetworkSession()
  84. {
  85.     // close up enpoint
  86.         if(fEndPoint !=  kOTInvalidEndpointRef)    ::OTCloseProvider(fEndPoint);
  87.         if( fData) delete fData;
  88. };
  89.  
  90.  
  91. // ---------------------------------------------------------------------------
  92. //     TNetworkAcceptor::Done(  )
  93. // ---------------------------------------------------------------------------
  94. //    Session Thread completed..
  95.  
  96. void TNetworkSession::Done()
  97. {
  98.     OTResult state = ::OTGetEndpointState(fEndPoint);
  99.     
  100. // If your not shutdown yet
  101.     if(state == T_DATAXFER) {
  102.     
  103. // flush out all waiting data
  104.         fioStream << flush;
  105.             
  106. // and disconnect the endpoint
  107.     if( (fInfo.flags == T_COTS_ORD) || (fInfo.flags == T_TRANS_ORD))
  108.         ::OTSndOrderlyDisconnect(fEndPoint);
  109.     else 
  110.         ::OTSndDisconnect (fEndPoint,&fCallInfo);
  111.         }
  112.         
  113. }
  114.  
  115.  
  116.  
  117. // ---------------------------------------------------------------------------
  118. //     TNetworkSession::HandleEvent (TNetworkEvent*)
  119. // ---------------------------------------------------------------------------
  120. //    Network Server Event Handler
  121.  
  122. void TNetworkSession::HandleEvent (TNetworkEvent* theEvent)
  123. {
  124.     switch ( theEvent->fEvent ){
  125.  
  126. ///// OpenEndpoint Completed
  127.             case T_OPENCOMPLETE:    
  128.                      EventOpenComplete(theEvent);
  129.                     break;
  130. ///// Endpoint accepted connection 
  131.             case T_PASSCON:    
  132.                      EventPassCon(theEvent);
  133.                     break;
  134. ///// Client Quit 
  135.             case T_DISCONNECT:                
  136.                     EventDisconnect(theEvent);
  137.                     break;
  138. ///// remote client request release
  139.             case T_ORDREL:
  140.                     EventOrdRelease(theEvent);
  141.                     break;
  142. ///// Connection Torn Down
  143.             case T_DISCONNECTCOMPLETE:
  144.                     EventDisconnectComplete(theEvent);
  145.                     break;
  146. ///// Winding down
  147.             case T_UNBINDCOMPLETE:
  148.                     EventUnbindComplete(theEvent);
  149.                     break;
  150. //// Data Available
  151.             case T_DATA:
  152.                     EventDataAvail(theEvent);
  153.                     break;
  154. //// Expidited Data Available
  155.             case T_EXDATA:
  156.                     EventExDataAvail(theEvent);
  157.                     break;
  158. //// No-copy memory was released        // DEBUG ONLY...
  159.         case T_MEMORYRELEASED:
  160.                     EventMemoryReleased(theEvent);
  161.                     break; 
  162. ////..Other ...
  163.             default:
  164.                     EventOther(theEvent);
  165.                     break;
  166.         }
  167. }
  168.  
  169.  
  170. // ---------------------------------------------------------------------------
  171. //     TNetworkSession::EventOpenComplete(theEvent )
  172. // ---------------------------------------------------------------------------
  173. //    Network Endpoint Open Completion Handler
  174.  
  175. void TNetworkSession::EventOpenComplete(TNetworkEvent* theEvent)
  176. {
  177. // record endpoint 
  178.     fEndPoint = (EndpointRef) theEvent->fParam;
  179.     
  180. // Setup Tcall/Tdisconnect area
  181.     fCallInfo.addr.len             = 0;
  182.     fCallInfo.opt.len                 = 0;
  183.     fCallInfo.udata.len             = 0;
  184.     fDisconInfo.udata.len        = 0;
  185.  
  186.     fCallInfo.addr.maxlen     = (fInfo.addr == T_INVALID)?0:fInfo.addr;
  187.     fCallInfo.opt.maxlen         = (fInfo.options == T_INVALID)?0:fInfo.options;
  188.     fCallInfo.udata.maxlen     = (fInfo.connect == T_INVALID)?0:fInfo.connect; 
  189.     fDisconInfo.udata.maxlen= (fInfo.discon == T_INVALID)?0:fInfo.discon;
  190.  
  191. // Alloacte enough ram for Tcall & TDiscon buffers
  192.     size_t buffSize    = fCallInfo.addr.maxlen 
  193.                                         + fCallInfo.opt.maxlen 
  194.                                          + (fCallInfo.udata.maxlen > fDisconInfo.udata.maxlen 
  195.                                                      ? fCallInfo.udata.maxlen
  196.                                                      : fDisconInfo.udata.maxlen);
  197.                                          
  198.     fData = new UInt8[buffSize];
  199.  
  200.     fCallInfo.addr.buf              = &fData[0];
  201.     fCallInfo.opt.buf              = fCallInfo.addr.buf + fCallInfo.addr.maxlen;
  202.     fCallInfo.udata.buf          = fCallInfo.opt.buf + fCallInfo.opt.maxlen;
  203.     fDisconInfo.udata.buf     = fCallInfo.udata.buf;     // Disconnect and connect share the same data area
  204.  
  205. // Enable AckSends
  206.     ThrowIfOTErr( ::OTAckSends(fEndPoint));
  207.  
  208. // attach endpoint to stream;
  209.     fioStream.attach(fEndPoint,&fInfo);
  210.  
  211. // Inform Server that we are ready to be used
  212.         QUEUE_NET_EVENT( fServer, TNetworkAcceptor::kSessionAvailable, noErr, this);
  213.     
  214. }
  215.  
  216. // ---------------------------------------------------------------------------
  217. //     TNetworkSession::EventPassCon(theEvent)
  218. // ---------------------------------------------------------------------------
  219. //    Network Endpoint Handoff Completion Handler
  220.  
  221. void TNetworkSession::EventPassCon(TNetworkEvent* theEvent)
  222. {
  223.     try{
  224.         Start();            // start thread.
  225.     } 
  226.     catch(...){
  227.         Done();
  228.     }
  229. }
  230.  
  231.  
  232. // ---------------------------------------------------------------------------
  233. //     TNetworkAcceptor::EventDisconnect 
  234. // ---------------------------------------------------------------------------
  235. //    Connecting client quit
  236.  
  237. void TNetworkSession::EventDisconnect(TNetworkEvent* theEvent)
  238. {
  239.     OSStatus ErrNo;
  240.         
  241.         if( ErrNo = ::OTRcvDisconnect(fEndPoint, &fDisconInfo)) 
  242.             ErrNo = ErrNo ;
  243.  
  244.         if( ErrNo = ::OTUnbind(fEndPoint)) ;
  245.             ErrNo = ErrNo ;
  246.     
  247. }
  248.  
  249. // ---------------------------------------------------------------------------
  250. //     TNetworkSession::EventOrdRelease 
  251. // ---------------------------------------------------------------------------
  252. //    remote client request release
  253.  
  254. void TNetworkSession::EventOrdRelease(TNetworkEvent* theEvent)
  255. {
  256.     OSStatus ErrNo;
  257.  
  258.         if( ErrNo = ::OTRcvOrderlyDisconnect(fEndPoint)) 
  259.             ErrNo = ErrNo ;
  260.  
  261.         if( ErrNo = ::OTUnbind(fEndPoint)) ;
  262.             ErrNo = ErrNo ;
  263.  
  264. // shut down thread if still running
  265.         Stop();
  266.  
  267. }
  268.  
  269.  
  270. // ---------------------------------------------------------------------------
  271. //     TNetworkSession::EventDisconnectComplete 
  272. // ---------------------------------------------------------------------------
  273. //    Connection Torn Down
  274.  
  275. void TNetworkSession::EventDisconnectComplete(TNetworkEvent* theEvent)
  276. {
  277.     OSStatus ErrNo;
  278.         if( ErrNo = ::OTUnbind(fEndPoint)) ;
  279.             ErrNo = ErrNo ;
  280. }
  281.  
  282. // ---------------------------------------------------------------------------
  283. //     TNetworkSession::EventUnbindComplete 
  284. // ---------------------------------------------------------------------------
  285. //    Network Endpoint Unbind Completion Handler
  286.  
  287. void TNetworkSession::EventUnbindComplete(TNetworkEvent* theEvent)
  288. {
  289.         
  290. // notify server that your done...
  291.         QUEUE_NET_EVENT( fServer, TNetworkAcceptor::kSessionAvailable  , noErr, this);
  292. }
  293.  
  294.  
  295. // ---------------------------------------------------------------------------
  296. //     TNetworkSession::EventDataAvail 
  297. // ---------------------------------------------------------------------------
  298. //  Data Available
  299.  
  300.  
  301. void TNetworkSession::EventDataAvail(TNetworkEvent* theEvent)
  302. {
  303. #pragma unused (theEvent)
  304.         OTFlags             flags;
  305.         OTResult            status;
  306.         OTBuffer*            buffP;
  307.         OTBufferInfo    buffInfo;
  308.         size_t                actCount;
  309.         char*                    buffer;
  310.             
  311. // do while data left in OT
  312.     while((status = ::OTRcv(fEndPoint, &buffP, kOTNetbufDataIsOTBufferStar, &flags)) > 0) {
  313.         
  314.     // get count of bytes in buffer
  315.             OTInitBufferInfo(&buffInfo, buffP);
  316.     
  317.     // loop until no longer hungry 
  318.         do{
  319.     // reserve buffer space
  320.                 ThrowIfNil( buffer = fioStream.ReserveBuffer(status, &actCount));
  321.             
  322.     // read data into buffer
  323.              ::OTReadBuffer(&buffInfo, buffer, &actCount);
  324.              fioStream.EnqueueBuffer(buffer,actCount);
  325.         
  326.             status -= actCount;
  327.              
  328.         } while( status > 0 );
  329.         
  330.     // return OTBuffer to system
  331.         ::OTReleaseBuffer(buffP);
  332.     }    
  333.     
  334.  
  335. // Did we read all the data
  336.          if(status ==  kOTNoDataErr) return;
  337.  
  338. // was  the endpoint not ready yet
  339.          else if(status ==  kOTStateChangeErr) QUEUE_NET_EVENT(this, T_DATA, 0, 0);
  340.                     
  341. // Check for Rcv Error 
  342.         else ThrowIfOTErr( status );    
  343.  
  344. };
  345.                     
  346. // ---------------------------------------------------------------------------
  347. //     TNetworkSession::EventExDataAvail 
  348. // ---------------------------------------------------------------------------
  349. //   Expidited Data Available
  350.  
  351. void TNetworkSession::EventExDataAvail(TNetworkEvent* theEvent)
  352. {
  353. };
  354.  
  355. // ---------------------------------------------------------------------------
  356. //     TNetworkSession::EventMemoryReleased(theEvent )
  357. // ---------------------------------------------------------------------------
  358. //    Network Endpoint Memory released hander
  359.  
  360. void TNetworkSession::EventMemoryReleased(TNetworkEvent* theEvent)
  361. {
  362.     TNetworkBuf::Release((void*)theEvent->fParam );
  363. }
  364.  
  365.             
  366.  
  367. // ---------------------------------------------------------------------------
  368. //     TNetworkSession::EventOther 
  369. // ---------------------------------------------------------------------------
  370. //    Other random event
  371.  
  372. void TNetworkSession::EventOther(TNetworkEvent* theEvent)
  373. {        
  374.         if(theEvent)
  375.             ThrowIfOTErr(noErr);
  376. };
  377.  
  378.